package service.impl;

import com.alibaba.fastjson.JSON;
import org.jsoup.Jsoup;
import pojo.*;
import service.ImageService;
import util.CollectionRandomUtil;
import util.ImageProcessUtil;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 官网图片爬取
 */
public final class OfficialWebsiteImageServiceImpl implements ImageService {
	public static final OfficialWebsiteImageServiceImpl INSTANCE = new OfficialWebsiteImageServiceImpl();

	/** 图片爬取的根地址 */
	public static final String BASEURL = "https://sc2.blizzard.cn/media";
	/** 缩略图地址，主要用于获取图片ID */
	public static final String THUMBNAIL = BASEURL + "/thumbnail-page";
	/** 单个图片地址请求地址 */
	public static final String META_DATA = BASEURL + "/meta-data";

	private OfficialWebsiteImageServiceImpl() {
	}

	/** 获取图片ID */
	public static ThumbnailResponse getThumbnail(CommandData command) throws IOException {
		HashMap<String, String> data = new HashMap<>();

		ImageType imageType = ImageType.valueOf(command.getSort().toUpperCase());
		// 随机某一页
		int page = random.nextInt(imageType.getPageCount() + 1);
		data.put("page", page + "");

		data.put("dataKey", command.getSort());

		data.put("keywords", command.getKeyword() != null ? command.getKeyword() : "");

		// 缩略图的请求，这里只是为了ID
		String jsonData = Jsoup.connect(THUMBNAIL)
				.data(data)
				.timeout(10000)
				.ignoreContentType(true)
				.get()
				.body()
				.text();
		return JSON.parseObject(jsonData, ThumbnailResponse.class);
	}

	/** 根据图片ID和指定大小下载图片到本地 */
	public static String imageDownload(String id, CommandData command) throws IOException {
		// 获取图片下载地址
		String jsonData = Jsoup.connect(META_DATA)
				.data("id", id)
				.data("dataKey", command.getSort())
				.timeout(10000)
				.ignoreContentType(true)
				.get()
				.text();
		OWImage owImage = JSON.parseObject(jsonData, OWImage.class);
		owImage.setDownloadUrl(JSON.parseObject(owImage.getDetailJson(), OWImage.DownloadUrl.class));
		String url;
		switch (command.getSize()) {
			case S1:
				url = owImage.getDownloadUrl().getIndexThumb();
				break;
			case S2:
				url = owImage.getDownloadUrl().getSmall();
				break;
			case S4:
				url = owImage.getDownloadUrl().getFull();
				break;
			default:
				url = owImage.getDownloadUrl().getLarge();
		}
		String suffix = ImageProcessUtil.getImageSuffixByUrl(url);
		String filePath = SAVE_PATH + "/" + id + command.getSize() + "." + suffix;
		ImageProcessUtil.imageDownload(url, filePath);
		return filePath;
	}

	@Override
	public List<ImageSource> getImageDownloadLink(CommandData command) throws IOException {
		// 获取图片ID
		ThumbnailResponse thumbnail = getThumbnail(command);
		// 随件选取指定个数
		return CollectionRandomUtil.randomOrder(thumbnail.getMedias(), command.getCount());
	}

	@Override
	public List<LocalImage> downloadImage(CommandData command, List<ImageSource> imageSources) {
		// 下载图片
		return imageSources.parallelStream()
				.map(imageUrl -> {
					String id = imageUrl.getId();
					String filePath = SAVE_PATH + "/" + id + command.getSize() + ".";
					// 先检查本地是否已有该图片
					for (String suffix : COMMON_SUFFIX) {
						if (!new File(filePath + suffix).isFile()) continue;
						return new LocalImage(filePath + suffix, imageUrl);
					}

					// 下载该图片
					try {
						filePath = imageDownload(id, command);
						return new LocalImage(filePath, imageUrl);
					} catch (IOException | RuntimeException e) {
					}
					return null;
				})
				.filter(Objects::nonNull) //过滤掉失败的
				.collect(Collectors.toList());
	}

	@Override
	public Map<String, String> getSortMap() {
		return Arrays.stream(ImageType.values())
				.collect(Collectors.toMap(ImageType::getDescription, ImageType::toString));
	}
}
